package com.nit.bike.service.bike.impl;

import com.nit.bike.dto.basic.UserDTO;
import com.nit.bike.dto.bike.CardDTO;
import com.nit.bike.dto.utils.OpResultDTO;
import com.nit.bike.entity.bike.CardEntity;
import com.nit.bike.mapper.bike.CardMapper;
import com.nit.bike.service.basic.UserService;
import com.nit.bike.service.bike.CardService;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

@Service
public class CardServiceImpl implements CardService {

    @Resource
    private CardMapper cardMapper;
    @Resource
    private UserService userService;

    @Override
    public CardDTO query(Long userId) throws Exception {
        CardDTO cardDTO = cardMapper.queryByUserId(userId);
        if (cardDTO == null) {
            cardDTO = cardMapper.queryLastCard(userId);
        }
        return cardDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized OpResultDTO add(Long userId) throws Exception {
        OpResultDTO op = new OpResultDTO();
        CardDTO cardDTO = query(userId);
        if (cardDTO != null && cardDTO.getCardState() == 0) {
            op.setMessage("error");
            op.setResult("用户已绑定租借卡！");
            return op;
        }
        CardEntity entity = new CardEntity();
        entity.setUserId(userId);
        cardDTO = cardMapper.queryLastCard(userId);
        if (cardDTO != null) {
            entity.setDuring(cardDTO.getDuring());
            entity.setDistance(cardDTO.getDistance());
            entity.setBalance(cardDTO.getBalance());
        }
        Date now = new Date();
        entity.setGmtCreate(now);
        entity.setGmtModify(now);
        cardMapper.insertSelective(entity);
        Long cardId = cardMapper.queryCardId();
        String cardNumber = String.format("c%08d", cardId);
        cardMapper.updateCardNumber(cardId, cardNumber);
        userService.updateCardId(userId, cardId);
        op.setMessage("success");
        op.setResult(cardDTO);
        return op;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO update(CardDTO cardDTO) throws Exception {
        OpResultDTO op = new OpResultDTO();
        UserDTO userDTO = userService.getByCardId(cardDTO.getCardId());
        if (!cardDTO.getCardId().equals(userDTO.getCardId())) {
            op.setMessage("error");
            op.setResult("过期或错误的租借卡信息！");
        }
        MapperFactory factory = new DefaultMapperFactory.Builder().build();
        CardEntity entity = factory.getMapperFacade().map(cardDTO, CardEntity.class);
        op.setMessage("success");
        op.setResult(cardMapper.updateByPrimaryKeySelective(entity));
        return op;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateData(CardEntity entity) throws Exception {
        return cardMapper.updateData(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public OpResultDTO remove(Long userId, Long cardId) throws Exception {
        OpResultDTO op = new OpResultDTO();
        op.setMessage("error");
        CardDTO cardDTO = query(userId);
        if (cardDTO.getCardId() == null || !cardDTO.getCardId().equals(cardId)) {
            op.setResult("过期或错误的租借卡信息！");
            return op;
        }
        UserDTO userDTO = userService.getByUserId(userId);
        if (userDTO.getRideId() != null) {
            op.setResult("用户正在骑行，无法挂失，请先还车！");
            return op;
        }
        op.setMessage("success");
        op.setResult(cardMapper.updateState(cardId));
        return op;
    }
}
